package edu.wschina.module_c_hanoitower;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Stack;
import java.util.UUID;

import edu.wschina.module_c_hanoitower.databinding.ActivityGameBinding;


public class GameActivity extends AppCompatActivity {

    private static final String TAG = "GameActivity";
    // 每个塔柱的圆盘状态towers.get(0);
    private List<Stack<Integer>> towers;
    int from = 0;
    int to = 0;
    private ActivityGameBinding binding;
    private boolean over = false;
    private int moves = 0;
    private int duration = 0;
    private float limit_second = 60;
    // 当前拖动的x坐标
    private float dragX = -1;
    // 当前拖动的y坐标
    private float dragY = -1;
    // 当前正在拖动的圆盘
    private int draggingDisk = -1;
    TowersView towersView;

    // 选中塔柱
    private int startTowerIndex = -1;
    // 目标塔柱
    private int endTowerIndex = -1;

    FrameLayout frameLayout;
    private  Handler handler = new Handler();
    private  Runnable timer = new Runnable() {
        @Override
        public void run() {
            if (over)
                return;

            handler.postDelayed(timer, 1000);
            binding.information.setText(String.format("Moves: %d, Timer: %d", moves, Math.round(duration)));
            duration += 1;

            if (duration >= limit_second) {
                over = true;
                showResult("游戏失败！");
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityGameBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        //初始化游戏
        init();

        /*@description:
        增加拖拽事件；
        @author aimin 2025-01-08 12:42:50*/
        frameLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                //当前触控的绝对坐标；
                float x = motionEvent.getX();
                float y = motionEvent.getY();

                //拖动逻辑
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //根据x坐标计算出触控的塔的索引
                        startTowerIndex = (int) (x / 600);
                        //判断是否该塔中的圆盘为空
                        if (!towers.get(startTowerIndex).isEmpty()) {
                            //peak()获取栈顶元素；
                            draggingDisk = towers.get(startTowerIndex).peek();
                            dragX = x;
                            dragY = y;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (draggingDisk != -1) {
                            dragX = x;
                            dragY = y;
//                            invalidate();
                        }
                        break;

                    case MotionEvent.ACTION_UP:
                        if (draggingDisk != -1) {
                            FrameLayout layout=findViewById(R.id.frameLayout);
                            int diskHGap = layout.getWidth() / MyApp.getInstance().diskCount; // 塔柱间距
                            endTowerIndex = (int) (x / diskHGap);
                            Log.d(TAG, endTowerIndex + "");

                            //移动
                            if (moveDisk(startTowerIndex, endTowerIndex)) {
                                moves++;  // 每移动一次圆盘，步数加1
                                //判断是否胜利
                                if (towers.get(2).size() == MyApp.getInstance().diskCount) {
                                    over = true;
                                    handler.removeCallbacks(timer);

                                    //获取日期和时间字符串
                                    Date currentDate = new Date();
                                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    String date = formatter.format(currentDate);
                                    int difference = moves - MyApp.getInstance().should;

                                    JSONObject json = new JSONObject();
                                    try {
                                        String id=UUID.randomUUID().toString();
                                        json.put("id",id);
                                        json.put("nickname",MyApp.getInstance().nickName);
                                        json.put("moves",moves);
                                        json.put("difference",difference);
                                        json.put("duration",duration);
                                        json.put("level",MyApp.getInstance().diskCount);
                                        json.put("date",date);
                                        MyApp.getInstance().addItem(id,json);
//                                        RankItem item = new RankItem(UUID.randomUUID().toString(), MyApp.getInstance().nickName, moves, difference, duration, MyApp.getInstance().diskCount + "", date);
//                                        MyApp.getInstance().addItem(item);
                                    } catch (JSONException e) {
                                        Log.d(TAG,"JSONObject Error");
                                    }
                                    showResult("Game Over! Congratulations!");
                                }
                            } else {
                                //如果移动不成功，则初始化以下变量；
                                draggingDisk = -1;
                                startTowerIndex = -1;
                                endTowerIndex = -1;
                                dragX = -1;
                                dragY = -1;
                            }
                            towersView.invalidate();
                        }
                        break;
                }
                return true;
            }
        });

        binding.tvGuide.setOnClickListener(view -> {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setCancelable(false);
            builder.setMessage("你要将所有的盘子从 Tower 1 移动到 Tower 3，你每次只能移动一个盘子，游戏最重要的规则是大的盘子不能放在小的盘子上面！");
            builder.setPositiveButton("我明白了", (v, w) -> {
                handler.post(timer);
            });
            builder.show();
            handler.removeCallbacks(timer);
        });

        //undo
        binding.ivUndo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (endTowerIndex == -1 || startTowerIndex == -1)
                    return;

                if (refactor(endTowerIndex, startTowerIndex))
                    moves--;
                towersView.invalidate();
            }
        });

        //redo
        binding.ivRedo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (endTowerIndex == -1 || startTowerIndex == -1)
                    return;

                if (refactor(startTowerIndex, endTowerIndex))
                    moves++;
                towersView.invalidate();

            }
        });

        binding.ivReset.setOnClickListener(View->{
            init();
        });

        binding.back.setOnClickListener(view -> {
            handler.removeCallbacks(timer);
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("游戏正在进行中，推出会丢失当前游戏数据，确认退出吗？");
            builder.setPositiveButton("否", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    handler.post(timer);
                }
            });

            // 设置取消按钮及其点击事件
            builder.setNegativeButton("是", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    startActivity(new Intent(getApplicationContext(), HomeActivity.class));
                    finish();
                }
            });
            builder.show();
        });
    }

    private boolean refactor(int from, int to) {
        if (moveDisk(from, to)) {
            return true;
        }
        return false;
    }

    private void init() {

        //避免再次单击，时间变快
        handler.removeCallbacks(timer);

        over = false;
        this.moves = 0;
        this.duration = 0;

           /*@description:
        1.初始化3个塔；
        2.说明：每个塔中保存着当前圆盘的舒朗
        @author aimin 2025-01-07 19:57:02*/
        towers = new ArrayList<>();
        for (int i = 0; i < MyApp.getInstance().towerCount; i++) {
            towers.add(new Stack<>());
        }

        // 将所有圆盘放到第一个塔柱
        // 从上而下：1、2、3;最下面的最大；
        for (int i = 0; i < MyApp.getInstance().diskCount; i++) {
            towers.get(0).push(i);
        }

        /*@description:
        将绘图区域DiskView添加到布局当中；
        @author aimin 2025-01-08 15:13:30*/
        frameLayout = findViewById(R.id.frameLayout);  // 获取FrameLayout
        towersView = new TowersView(this, towers);
        frameLayout.removeAllViews();
        frameLayout.addView(towersView);

        handler.post(timer);

        int should = MyApp.getInstance().should;
        binding.tips.setText(String.format("At least %d moves", should));
    }


    private boolean moveDisk(int from, int to) {
        //如果选中的塔为空，返回失败
        if (towers.get(from).isEmpty()) return false;

        //获取选中的塔中的顶端的圆盘
        int from_disk = towers.get(from).peek();
        Log.d(TAG, "source:" + from_disk);

        // 圆盘移动条件判断。说明：disk越大，其值越小；
        //1.目标塔柱为空，
        //2.目标塔柱顶端的圆盘，大于正在移动的塔柱，也就是from_disk的值需要大于to_disk的值
        if (towers.get(to).isEmpty() || from_disk > towers.get(to).peek()) {

            //将from塔柱的顶端元素弹出pop，在压入目标塔柱to。
            towers.get(to).push(towers.get(from).pop());

            return true;
        }
        //不能移动
        return false;
    }


    private void showResult(String msg) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(msg);
        builder.setNegativeButton("返回", (dialog, which) -> {
            init();
//            startActivity(new Intent(this, GameActivity.class));
//            finish();
        });
        builder.setPositiveButton("前往排行", (dialog, which) -> {
            startActivity(new Intent(this, RankActivity.class));
            finish();
        });
        builder.setCancelable(false);
        builder.show();


    }

//    private void showAlertDialog(String msg) {
//        AlertDialog.Builder builder = new AlertDialog.Builder(this);
//        builder.setMessage(msg);
//        LayoutInflater inflater = LayoutInflater.from(this);
////        View dialogView = inflater.inflate(R.layout.dialog, null);
////        builder.setView(dialogView);
//        AlertDialog dialog = builder.create();
//
//
//        dialog.show();
//    }


}

